import { Modal, message, Input, Upload } from 'antd';
import { Graph, Cell, DataUri } from '@antv/x6';
import {
  nextTick,
  getGraphJSONData,
  autoSaveJson,
  launchFullScreen,
  exitFullscreen,
} from './tools';
import React from 'react';

const { Dragger } = Upload;

// 文件解析
const fileExplain = (file: File) => {
  const reader = new FileReader();
  reader.readAsText(file);
  reader.onload = async function (event) {
    Modal.destroyAll();
    try {
      const jsonData = JSON.parse((event.target?.result as string) || '[]');
      message.success('文件解析完成');
      await autoSaveJson(jsonData, null);
      window.location.reload();
    } catch (e) {
      message.error('文件解析失败');
    }
  };
  Modal.info({
    closable: false,
    className: 'rasir-fc-model',
    title: '文件解析',
    content: '文件解析中，请稍等...',
    okButtonProps: { disabled: true },
  });
};

export default function useHooks({
  onRemoveLink,
  onRemoveNode,
  changeCells,
  onAddLink,
  onSave,
  defaultEdgeShape,
}: any) {
  const actionFunMap: {
    [key: string]: (...args: any) => void;
  } = {
    // 编辑节点
    edite: (_: Cell, __: Graph, config: any) => {
      const { setVisible } = config;
      setVisible(true);
    },
    // 删除节点或连线
    delete: (cell: Cell, graph: Graph) => {
      let cellItems: any[] = [];
      if (cell) cellItems = [cell];
      else {
        // 如果currentCell没有值 就去graph中找有没有被选中的节点
        cellItems = graph.getSelectedCells();
      }
      if (!cellItems.length) {
        message.info('请先选择要删除的节点', {
          duration: 1000,
        } as any);
        return;
      }
      const isNode = cellItems[0].isNode();
      const isEdge = cellItems[0].isEdge();
      // 删除节点
      if (isNode) {
        Modal.confirm({
          title: '删除节点',
          className: 'rasir-fc-model',
          content: `该操作将删除节点 ${cellItems
            .map((cell) => cell.label)
            .join(',')} 是否继续？`,
          okText: '确定',
          cancelText: '取消',
          centered: true,
          onOk: () =>
            new Promise(async (resolve, reject) => {
              if (
                !onRemoveNode ||
                (onRemoveNode &&
                  (await onRemoveNode(cellItems.map((cell) => cell.data))))
              ) {
                graph.removeCells(
                  cellItems.map((cell) => graph.getCellById(cell.data.id)),
                );
                resolve(1);
                changeCells();
              } else reject();
            }),
        });
      } else if (isEdge) {
        // 删除连线
        Modal.confirm({
          title: '删除连线',
          className: 'rasir-fc-model',
          content: `该操作将删除连线是否继续？请确认`,
          okText: '确定',
          cancelText: '取消',
          centered: true,
          onOk: () =>
            new Promise(async (resolve, reject) => {
              if (onRemoveLink && !(await onRemoveLink(cellItems))) {
                reject();
              } else {
                graph.removeCells(cellItems);
                resolve(1);
                changeCells();
              }
            }),
          onCancel() {
            cellItems.forEach((cellItem) => {
              graph.addCell(cellItem);
            });
          },
        });
      }
    },
    // 添加节点或连线
    add: async (cellItem: Cell, graph: Graph) => {
      const isEdge = cellItem.isEdge();
      if (isEdge) {
        message.loading({ duration: 0, content: '连接生成中，请稍等' });
        if (!(onAddLink && !(await onAddLink()))) {
          const { source, target } = cellItem as any;
          const edgeData = {
            id: `${source.cell}_${target.cell}`,
            source: source.cell,
            target: target.cell,
          };
          graph.addEdge({
            shape: defaultEdgeShape,
            data: {
              ...edgeData,
              type: 'link',
              zIndex: 1,
            },
            ...edgeData,
          });
          message.destroy();
          message.success('连接成功');
          changeCells();
        }
      }
    },
    // 缩小
    smaller: (_: Cell, __: Graph, { zoom, setZoom }) => {
      if (zoom <= 0.5) return;
      setZoom(zoom - 0.1);
    },
    // 放大
    bigger: (_: Cell, __: Graph, { zoom, setZoom }) => {
      if (zoom >= 1.5) return;
      setZoom(zoom + 0.1);
    },
    // 复制节点
    copy: (_: Cell, graph: Graph) => {
      const cellItems = graph.getSelectedCells();
      if (!cellItems.length) return message.info('请先选择要复制的节点');
      if (cellItems.length > 1) return message.info('一次只能复制一个节点');
      graph.copy(cellItems);
      message.success('节点成功放入剪贴板');
    },
    // 粘贴节点
    paste: (_: Cell, graph: Graph, { setVisible, setCurrentCell }) => {
      if (!graph.isClipboardEmpty()) {
        const [cell] = graph.getCellsInClipboard();
        graph.cleanSelection();
        cell.setData({ id: null }, { deep: true });
        setCurrentCell(cell);
        nextTick(() => setVisible(true));
      } else {
        message.info('剪贴板中没有节点');
      }
    },
    // 导出图片
    exportImg: (_: Cell, graph: Graph) => {
      let chartName: string | undefined = undefined;
      Modal.confirm({
        title: '导出图片',
        className: 'rasir-fc-model',
        cancelText: '取消',
        okText: '确定',
        width: 500,
        onOk: () =>
          new Promise((resolve, reject) => {
            if (!chartName) {
              message.info('请输入图片名称');
              reject();
            } else {
              graph.toPNG(
                (dataUri: string) => {
                  // 下载
                  DataUri.downloadDataUri(dataUri, `${chartName}.png`);
                  resolve(1);
                },
                {
                  quality: 1,
                  padding: {
                    top: 20,
                    right: 20,
                    bottom: 20,
                    left: 20,
                  },
                },
              );
            }
          }),
        content: (
          <Input
            value={chartName}
            onChange={(e) => (chartName = e.target.value)}
            placeholder="请输入图片名称"
          />
        ),
      });
    },
    // 保存到后端
    save: (_: Cell, graph: Graph) => {
      if (!onSave) return;
      Modal.confirm({
        title: '数据上传',
        className: 'rasir-fc-model',
        content: `该操作将数据上传到云端，请确认`,
        okText: '确定',
        cancelText: '取消',
        centered: true,
        onOk: () =>
          new Promise(async (resolve, reject) => {
            const ret = await onSave(getGraphJSONData(graph));
            if (ret) {
              message.success('上传成功！');
              resolve(1);
            } else {
              reject();
            }
          }),
      });
    },
    // 导出数据文件
    exportData: (_: Cell, graph: Graph) => {
      let fileName = '';
      Modal.confirm({
        title: '导出文件',
        className: 'rasir-fc-model',
        content: (
          <div>
            <Input
              onChange={(e) => (fileName = e.target.value)}
              placeholder="请输入文件名称"
            ></Input>
          </div>
        ),
        okText: '确定',
        cancelText: '取消',
        onOk: () => {
          if (!fileName) {
            message.error('请输入文件名称');
            return Promise.reject();
          }
          try {
            const content = JSON.stringify(getGraphJSONData(graph));
            const file = new Blob([content], { type: 'application/json' });
            const fileUrl = URL.createObjectURL(file);
            const linkElement = document.createElement('a');
            linkElement.setAttribute('href', fileUrl);
            linkElement.setAttribute('download', `${fileName}.json`);
            linkElement.click();
            return Promise.resolve(1);
          } catch (e) {
            message.error('数据导出失败');
            return Promise.resolve(1);
          }
        },
      });
    },
    // 导入文件数据
    importData: (_: Cell) => {
      Modal.confirm({
        title: '导入数据',
        okText: '确定',
        cancelText: '取消',
        className: 'rasir-fc-model',
        content: (
          <Dragger
            action="/"
            fileList={[]}
            beforeUpload={(file: any) => {
              Modal.destroyAll();
              fileExplain(file);
              return Promise.reject();
            }}
          >
            <p style={{ fontSize: 40 }}>+</p>
            <p>请选择要导入的数据</p>
          </Dragger>
        ),
      });
    },
    // 清理缓存数据
    clearStorage: (_: Cell) => {
      Modal.confirm({
        title: '清理缓存',
        className: 'rasir-fc-model',
        content: `该操作将清理缓存数据，请确认`,
        okText: '确定',
        cancelText: '取消',
        centered: true,
        onOk: async () => {
          await autoSaveJson(null, null);
          window.location.reload();
        },
      });
    },
    // 全屏
    full: (_: Cell, __: Graph, { fullContainer, changeFullScreeen }) => {
      launchFullScreen(fullContainer);
      nextTick(() => changeFullScreeen(true));
    },
    // 取消全屏
    normal: (_: Cell, __: Graph, { changeFullScreeen }) => {
      exitFullscreen();
      nextTick(() => changeFullScreeen(false));
    },
    // 撤销
    undo: (_: Cell, graph: Graph) => {
      const history = graph.history;
      history.undo();
    },
    // 重做
    redo: (_: Cell, graph: Graph) => {
      const history = graph.history;
      history.redo();
    },
  };
  return {
    actionFunMap,
  };
}
